home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/perl -w
-
- #################################################
- # feedback.pl
- # Customer feedback to email form
- # Matt Kynaston (kynaston@yahoo.com), 2001
- # sample feedback form for .net magazine's CGI series, issue 82
- # www.netmag.co.uk
- # use, abuse, modify or mock,
- # just don't hold me responsible
- #
- # I've made a number of additions to the example code printed
- # in the magazine. I've done my best to comment them so you
- # can see the techniques I've employed.
-
- #################################################
- # use standard CGI module.
-
- use CGI qw(:standard);
-
-
- #################################################
- # configuration section - modify to suit your environment
- # notice I've added a 'products' array
-
- $mailprog='sendmail -t'; # full path to mail program
- $recipient='kynaston@uklinux.net'; # return email address
- $returl='../index.html'; # page to forward to once done
- @products = ["Baby Bags","Goat Skis","Fish Lids"];
-
- # path to RobMail's adduser script, used to subscribe users to
- # the email newsletter.
- $adduser = '/cgi-bin/adduser.cgi';
-
- # set nosend to 1 to avoid dialing up and sending mail - good
- # for debugging locally
- $nosend = 0;
-
-
- #################################################
- # create new CGI object called $q
-
- $q = new CGI;
-
-
- #################################################
- # new: check form parameters and forward to correct section
-
- &check_form;
-
-
- #################################################
- # print_form
- # prints out form asking for name, email, product from
- # drop-down list, whether they want to subscribe to newsletter
- # submits it back to this script the return URL
- #
- # I've changed a couple of things from the version in the mag:
- # print_form can now be called from check_form, printing a
- # message at the top of the page. It will also automatically
- # repopulate its fields with the values typed previously
-
- sub print_form {
- print $q->header,
- $q->start_html(-bgcolor=>"#FF8000",
- -title=>"Customer Feedback Form"),
- $q->h1("Customer Feedback");
-
- # check to see if print_form called with an argument (from check_form)
- # if so, print out the message. @_ is an array containing all the arguments
- # passed to a function, $_[0] the first argument in this array
- if (@_) {
- print $q->hr,
- $q->p($_[0]),
- $q->hr;
- }
-
- print $q->start_form,
- $q->p("Your name: ",
- $q->textfield(-name=>"name",
- -default=>$q->param("name")),
- "*"),
- $q->p("Your email: ",
- $q->textfield(-name=>"from",
- -default=>$q->param("from")),
- "*"),
- $q->p("Which product are you using? ",
- $q->popup_menu(-name=>"product",
- -values=>@products,
- -default=>$q->param("product"))),
- $q->textarea(-name=>"comment",
- -default=>$q->param("comment") ? $q->param("comment") : "type your comments here",
- -rows=>10,
- -columns=>50),
- $q->p($q->checkbox(-name=>"newsletter",
- -checked=>$q->param("checked") ? "on" : undef,
- -label=>"Subscribe to newsletter?")),
- $q->p($q->font({-size=>"-1"}),"The * denotes required fields"),
- $q->p($q->submit("Send"), $q->defaults("Clear")),
- $q->end_form,
- $q->end_html;
- }
-
- #################################################
- # send_mail
- # sends formatted mail to the mail program
- # subscribes customer to RobMail newsletter (if appropriate)
- # thanks customer and automatically forwards to return URL or
- # sends on to newsletter submission (if requested)
-
- sub send_mail {
- # notice how I've added redirection to the header and
- # background colour to the body tag
- if ($q->param("newsletter") ne "on") {
- print $q->header(-Refresh=>"10; URL=$returl");
- } else { print $q->header }
-
- print start_html(-bgcolor=>"#8080FF",-title=>"Thank you!");
-
- if (!$nosend) {
- open (MAIL, "|$mailprog") || die_with_error("Can't open $mailprog! Error no: $!");
- print MAIL "To: $recipient\n",
- "From: ", $q->param("from"), "\n",
- "Subject: Customer Feedback\n",
- "Re - ", $q->param("product"), "\n\n",
- $q->param("comment"), "\n";
- close (MAIL) || die_with_error("Can't close $mailprog! Error no: $!");
- }
-
- print $q->h1("Thanks for your feedback, ", $q->param("name"));
-
- if ($q->param("newsletter") ne "on") {
- print $q->p("This page should automatically return you the main menu in 10 seconds."),
- $q->p("If it doesn't, just click the following link: ");
-
- } else {
- print $q->start_form(-action=>$adduser),
- $q->hidden(-name=>"name",-value=>$q->param("name")),
- $q->hidden(-name=>"email",-value=>$q->param("from")),
- $q->hidden(-name=>"what",-value=>"add"),
- $q->hidden(-name=>"list",-value=>"default"),
- $q->p("Click here to continue to newsletter subscription",
- $q->submit("Subscribe"),
- "or follow the link below:"),
- $q->end_form;
- }
- print $q->p($q->a({-href=>$returl},"Return to main menu")),
- $q->end_html;
- }
-
- #################################################
- # check_form
- # makes sure that all details filled in correctly, otherwise reprints
- # form. If OK, validates data then calls send_mail
- #
- # Uses a regular expression to check the email, which I haven't
- # had the space to discuss in the mag. The first part of the
- # 'elsif' statement basically states:
- # if the email parameter starts with one or more
- # hyphen, alpha-numerics or dots, followed by an '@' sign,
- # followed by one or more hyphen/alphanumerics/dots,
- # followed by a full stop plus one or more alphanumerics
- # characters, evaluate to true
- # OK, it's not exactly readable, but try creating such precise
- # string conditions any other way! See the perlre section of the
- # core Perl documentation and for more details
-
- sub check_form {
- if (!$q->param()) {
- &print_form;
- } elsif ($q->param("from") =~ /^[-\w\.]+\@[-\w\.]+\.\w+/ && $q->param("name") =~ /\w/) {
- foreach $pname ($q->param) {
- $q->param($pname, strip_unsafe($q->param($pname)));
- }
- &send_mail;
- } else {
- print_form("Please make sure you fill in all the required fields.");
- }
- }
-
- #################################################
- # strip_unsafe
- # performs some basic security by removing any characters that
- # may screw with the mail program. Sendmail is fairly robust, but
- # it's a good idea to perform similar validation on any data you
- # send to a program (or database) on your host's computer to
- # prevent a malicious user compromising security.
- # Notes: we do this by removing characters we haven't approved
- # (the ^ means "not in this list") rather than looking for possibly
- # troublesome characters, since there will always be some we
- # haven't thought of! Never approve the shell escape "\" unless
- # you're sure the program you're sending it to can handle it.
- #
- # This is pretty rudimentary, but it might stop casual meddlers.
- # For more information on securing your Perl scripts, take a
- # look at perlsec in the core Perl documentation and the notes
- # on Denial of Service in the CGI library documentation.
-
- sub strip_unsafe {
- $_ = $_[0];
- s/[^\s\w\+\-\@\,\.\!\?\/\(\)\[\{\}\"\'\รบ\$\%\&\*\~\#\<\>]//mg;
- return $_;
- }
-
- #################################################
- # die_with_error
- # prints error message to browser then dies
- # assumes that the content header has already been sent
-
- sub die_with_error {
- print $q->h1("An error occured while processing this script:"),
- $q->p($_[0]),
- $q->p("Try sending your comment again. If the problem persists, please contact the webmaster"),
- $q->end_html;
- die;
- }